﻿using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.WebControls;

namespace joelblogs.co.uk.GoogleMapsWebPart.GoogleMap
{
    /// <summary>
    /// Editor Part for the Google Map Web Part.
    /// </summary>
    class GoogleMapEditorPart : EditorPart
    {
        #region controls
        public TextBox width = new TextBox();
        public TextBox height = new TextBox();
        public HiddenField mapType = new HiddenField();
        public TextBox title = new TextBox();
        public TextBox label = new TextBox();
        public TextBox address = new TextBox();
        public TextBox latitude = new TextBox();
        public TextBox longitude = new TextBox();
        public TextBox centreLatitude = new TextBox();
        public TextBox centreLongitude = new TextBox();
        public TextBox zoom = new TextBox();
        public CheckBox displayZoom = new CheckBox();
        public CheckBox disableDragging = new CheckBox();
        public CheckBox icon = new CheckBox();

        public Button find = new Button();

        Label   messages = new Label();
        #endregion
        #region overrides

        /// <summary>
        /// Saves the values in an <see cref="T:System.Web.UI.WebControls.WebParts.EditorPart"/> control to the corresponding properties in the associated <see cref="T:System.Web.UI.WebControls.WebParts.WebPart"/> control.
        /// </summary>
        /// <returns>
        /// true if the action of saving values from the <see cref="T:System.Web.UI.WebControls.WebParts.EditorPart"/> control to the <see cref="T:System.Web.UI.WebControls.WebParts.WebPart"/> control is successful; otherwise (if an error occurs), false.
        /// </returns>
        public override bool ApplyChanges()
        {
            EnsureChildControls();
            GoogleMap webPart = ((GoogleMap)WebPartToEdit);
            try
            {
                webPart.MapType = mapType.Value;
                webPart.MapWidth = tryParseInt(width.Text, 400);
                webPart.MapHeight = tryParseInt(height.Text, 300);
                webPart.Latitude = tryParseDouble(latitude.Text, 0D);
                webPart.Longitude = tryParseDouble(longitude.Text, 0D);

                webPart.CentreLatitude = tryParseDouble(centreLatitude.Text, 0D);
                webPart.CentreLongitude = tryParseDouble(centreLongitude.Text, 0D);

                webPart.ZoomLevel = tryParseInt(zoom.Text, 13);

                webPart.PushpinTitle = title.Text;
                webPart.Address = address.Text;
                webPart.Label = label.Text;

                webPart.DisplayZoomControl = displayZoom.Checked;
                webPart.DisableDragging = disableDragging.Checked;
                webPart.DisplayIcon = icon.Checked;

                return true;
            }
            catch (Exception x)
            {
                messages.Text += x.Message;
                return false;
            }
            finally
            {
                webPart = null;
            }
        }

        /// <summary>
        /// Retrieves the property values from a <see cref="T:System.Web.UI.WebControls.WebParts.WebPart"/> control for its associated <see cref="T:System.Web.UI.WebControls.WebParts.EditorPart"/> control.
        /// </summary>
        public override void SyncChanges()
        {
            EnsureChildControls();
            GoogleMap webPart = ((GoogleMap)WebPartToEdit);
            try
            {
                mapType.Value = webPart.MapType;

                width.Text = webPart.MapWidth.ToString();
                height.Text = webPart.MapHeight.ToString();
                latitude.Text = webPart.Latitude.ToString();
                longitude.Text = webPart.Longitude.ToString();
                centreLatitude.Text = webPart.CentreLatitude.ToString();
                centreLongitude.Text = webPart.CentreLongitude.ToString();
                zoom.Text = webPart.ZoomLevel.ToString();
                label.Text = webPart.Label.ToString();
                title.Text = webPart.PushpinTitle.ToString();
                address.Text = webPart.Address.ToString();
                displayZoom.Checked = webPart.DisplayZoomControl;
                disableDragging.Checked = webPart.DisableDragging;
                icon.Checked = webPart.DisplayIcon;

            }
            catch
            {

            }
            finally
            {
                webPart = null;
            }
        }
        
        protected override void CreateChildControls()
        {
            Controls.Add(mapType);
            Controls.Add(width);
            Controls.Add(height);
            Controls.Add(title);
            Controls.Add(label);
            Controls.Add(address);
            Controls.Add(latitude);
            Controls.Add(longitude);
            Controls.Add(centreLatitude);
            Controls.Add(centreLongitude);
            Controls.Add(find);
            Controls.Add(zoom);
            Controls.Add(messages);
            Controls.Add(displayZoom);
            Controls.Add(disableDragging);
            Controls.Add(icon);
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            SyncChanges();
            writer.Write("<p><i>Instructions:</i><br/>Key in a Title and a Label for the pushpin if requied. Next, key in an Address and hit Find. If a location can be found it will centre the map there. You can set the Zoom Level with the +/- buttons on the map itself. You can also toggle the map between Roadmap and Satellite view. If you drag the Map or the Pushpin, the new location will be remembered when you hit OK or Apply.</p>");

            mapType.RenderControl(writer);
            writer.Write("<h3>Pushpin Settings</h3>");

            icon.RenderControl(writer);
            writer.Write("Display Pushpin<br/>");

            displayZoom.RenderControl(writer);
            writer.Write("Display zoom control<br/>");

            disableDragging.RenderControl(writer);
            writer.Write("Disable mouse dragging<br/>");

            writer.Write("Title<br/>");
            title.RenderControl(writer);

            writer.Write("<br/>Label<br/>");
            label.TextMode = TextBoxMode.MultiLine;
            label.Columns = 30;
            label.Rows = 5;
            label.RenderControl(writer);

            writer.Write("<br/>Address<br/>");
            address.RenderControl(writer);

            find.Text = "Find...";
            find.RenderControl(writer);
            writer.Write("<hr/>");

            writer.Write("<h3>Fine Tuning</h3>");
            writer.Write("Latitude<br/>");
            latitude.RenderControl(writer);

            writer.Write("<br/>Longitude<br/>");
            longitude.RenderControl(writer);

            writer.Write("<br/>Centre Latitude<br/>");
            centreLatitude.RenderControl(writer);

            writer.Write("<br/>Centre Longitude<br/>");
            centreLongitude.RenderControl(writer);

            writer.Write("<br/>Default Zoom Level<br/>");
            zoom.RenderControl(writer);


            writer.Write("<br/>");
            messages.RenderControl(writer);
        }
        #endregion
        #region privates
        /// <summary>
        /// Tries the parse int.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="defaultVal">The default val.</param>
        /// <returns></returns>
        private int tryParseInt(string value, int defaultVal)
        {
            int val;
            if (int.TryParse(value, out val))
                return val;
            else
                return defaultVal;
        }

        /// <summary>
        /// Tries the parse double.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="defaultVal">The default val.</param>
        /// <returns></returns>
        private double tryParseDouble(string value, double defaultVal)
        {
            double val;
            if (double.TryParse(value, out val))
                return val;
            else
                return defaultVal;
        }
        #endregion
    }
}
